package com.jifen.mch.service;

import com.jifen.config.Global;
import com.jifen.mch.dao.MchDao;
import com.jifen.mch.dao.MchJifenDetailDao;
import com.jifen.mch.dao.MchPayDao;
import com.jifen.mch.entity.*;
import com.jifen.mch.vo.MchBillVo;
import com.jifen.mch.vo.MchParam;
import com.jifen.mch.vo.MchInfoVo;
import com.jifen.mch.vo.QrCodeVo;
import com.jifen.user.dao.UserDao;
import com.jifen.user.dao.UserInviteProfitDao;
import com.jifen.user.entity.UserInviteProfit;
import com.jifen.user.service.UserService;
import com.jifen.user.vo.TokenUserVo;
import com.jifen.user.vo.UserJifenDetailVo;
import com.jifen.user.vo.UserParam;
import com.jifen.utils.DateUtils;
import com.jifen.utils.LonLatUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class MchService {

    @Autowired
    UserService userService;
    @Autowired
    MchDao mchDao;
    @Autowired
    MchJifenDetailDao mchJifenDetailDao;
    @Resource
    RedisTemplate<String, Object> redisTemplate;
    @Autowired
    UserDao userDao;
    @Autowired
    MchPayDao mchPayDao;
    @Autowired
    UserInviteProfitDao userInviteProfitDao;

    /**
     * 获取商家消费二维码
     * @param token
     * @param amount
     * @return
     */
    public Map<String, Object> getConsumeQrcode(String token, double amount){
        TokenUserVo tokenUser = userService.getTokenUser(token);
        Map<String, Object> map = new HashMap<>();
        Mch mch = mchDao.selectByPrimaryKey(tokenUser.getMchId());
        String content = "";
        if(mch!=null && mch.getType()==1){
            //content = "mch_"+mch.getId()+"_"+amount+"_"+UUID.randomUUID().toString();
            //content = AESUtils.encode(content);
            //content = content.replaceAll("\r|\n", "");
            content = UUID.randomUUID().toString();
/*            if(StringUtils.isBlank(content)) {
                throw new MyException(ErrorCode.QRCODE_FAIL);
            }*/
            QrCodeVo qrCodeVo = new QrCodeVo();
            qrCodeVo.setType(1);
            qrCodeVo.setConsumeAmount(amount);
            qrCodeVo.setMchId(mch.getId());
            qrCodeVo.setMchName(mch.getName());
            double jifenGiveRatio = mchDao.getJifenGiveRatio(mch.getId());
            double jifen = amount * jifenGiveRatio / 100;
            qrCodeVo.setJifen(jifen);
            redisTemplate.opsForValue().set(content, qrCodeVo, 5, TimeUnit.MINUTES);
        }
        map.put("qrcode", content);
        return map;
    }

    /**
     * 获取超市二维码
     * @param token
     * @param id
     * @param jifen
     * @return
     */
    public Map<String, Object> getSmarketQrCode(String token, int id, int jifen){
        TokenUserVo tokenUser = userService.getTokenUser(token);
        Map<String, Object> map = new HashMap<>();
        Mch mch = mchDao.selectByPrimaryKey(id);
        String content = "";
        if(mch!=null && mch.getType()==2){
            //content = "mch_"+mch.getId()+"_"+jifen+"_"+UUID.randomUUID().toString();
            //content = AESUtils.encode(content);
            //content = content.replaceAll("\r|\n", "");
            //if(StringUtils.isBlank(content)) {
            //    throw new MyException(ErrorCode.QRCODE_FAIL);
            // }
            content = UUID.randomUUID().toString();
            QrCodeVo qrCodeVo = new QrCodeVo();
            qrCodeVo.setType(2);
            qrCodeVo.setJifen(jifen);
            qrCodeVo.setMchId(mch.getId());
            qrCodeVo.setMchName(mch.getName());
            qrCodeVo.setConsumeAmount(jifen);
            BigDecimal deductMoney = new BigDecimal( qrCodeVo.getConsumeAmount()*0.8).setScale(2, RoundingMode.DOWN);
            BigDecimal payMoney = new BigDecimal( qrCodeVo.getConsumeAmount()*0.2).setScale(2, RoundingMode.DOWN);
            qrCodeVo.setDeductMoney(deductMoney.doubleValue());
            qrCodeVo.setPayMoney(payMoney.doubleValue());
            redisTemplate.opsForValue().set(content, qrCodeVo, 5, TimeUnit.MINUTES);
        }
        map.put("qrcode", content);
        return map;
    }

    /**
     * 积分明细
     * @param param
     * @return
     */
    public Map<String, Object> getJifenDetail(MchParam param){
        TokenUserVo tokenUser = userService.getTokenUser(param.getToken());
        param.setPageNo((param.getPageNo() - 1) * param.getPageSize());
        param.setId(tokenUser.getMchId());
        Map<String, Object> map = new HashMap<>();
        MchBillVo billVo = new MchBillVo();
        if(param.getQtype()==1) {
            // 总支出积分
            param.setType(2);
            Double totalJifen = mchJifenDetailDao.sumJifenByDay(param);
            if(totalJifen!=null) {
                billVo.setPayJifen(totalJifen);
            }
            // 总购买积分
            param.setType(1);
            totalJifen = mchJifenDetailDao.sumJifenByDay(param);
            if(totalJifen!=null) {
                billVo.setBuyJifen(totalJifen);
            }
        }
        map.put("total", billVo);
        List<MchJifenDetail> detailList = mchJifenDetailDao.selectPage(param);
        List<UserJifenDetailVo> voList = new ArrayList<>();
        for (int i = 0; i < detailList.size(); i++) {
            UserJifenDetailVo vo = new UserJifenDetailVo();
            BeanUtils.copyProperties(detailList.get(i), vo);
            vo.setDate(DateUtils.formatDate(detailList.get(i).getCreateTime(),"yyyy-MM-dd HH:mm:ss"));
            voList.add(vo);
        }
        map.put("details", voList);
        return map;
    }

    /**
     * 查询商超
     * @param param
     * @return
     */
    public List<MchInfoVo>searchMch(MchParam param){
        List<MchInfoVo> voList = new ArrayList<>();
        param.setPageNo((param.getPageNo() - 1) * param.getPageSize());
        List<Mch> list = mchDao.selectPage(param);
        for (int i = 0; i < list.size(); i++) {
            Mch mch = list.get(i);
            MchInfoVo vo = new MchInfoVo();
            vo.setId(mch.getId());
            vo.setName(mch.getName());
            vo.setHead(mch.getHead());
            vo.setAddress(mch.getAddress());
            vo.setLat(mch.getLat());
            vo.setLng(mch.getLng());
            if(StringUtils.isNotBlank(param.getLng())&&StringUtils.isNotBlank(param.getLat())&&StringUtils.isNotBlank(mch.getLng())&&StringUtils.isNotBlank(mch.getLat())) {
                vo.setDistance(LonLatUtils.getDistance(
                        Double.parseDouble(param.getLng()),
                        Double.parseDouble(param.getLat()),
                        Double.parseDouble(mch.getLng()), Double.parseDouble(mch.getLat())));
            }
            voList.add(vo);
        }
        return voList;
    }

    /**
     * 详情
     * @param id
     * @return
     */
    public MchInfoVo detail(int id){
        Mch mch = mchDao.selectByPrimaryKey(id);
        MchInfoVo vo = new MchInfoVo();
        vo.setId(mch.getId());
        vo.setType(mch.getType());
        vo.setName(mch.getName());
        vo.setAddress(mch.getAddress());
        vo.setPhone(mch.getPhone());
        vo.setJifenGiveRatio(mch.getJifenGiveRatio());
        vo.setIntroduce(mch.getIntroduce().replace("\n", ""));
        if(StringUtils.isNotBlank(mch.getSlidePic())) {
            String[] slidePics = mch.getSlidePic().split(",");
            for (int i = 0; i < slidePics.length; i++) {
                slidePics[i] = Global.getConfig("cdnUrl") + slidePics[i];
            }
            vo.setSlidePic(slidePics);
        }
        if(mch.getType()==2){
            // 超市
            vo.setContactPerson(userDao.getMobile(mch.getMuid()));
        }
        return vo;
    }

    /**
     * 获取行业
     * @return
     */
    public List<Industry> getIndustry(){
        return mchDao.getIndustrys();
    }

    /**
     * 修改商家信息
     * @param token
     * @param mchInfo
     */
    public void modifyMch(String token, Mch mchInfo){
        TokenUserVo tokenUser = userService.getTokenUser(token);
        Mch mch = mchDao.selectByPrimaryKey(tokenUser.getMchId());
        if(mch!=null){
            mchInfo.setId(mch.getId());
            if(StringUtils.isNotBlank(mchInfo.getSlidePic())) {
                String[] slidePics = mchInfo.getSlidePic().split(",");
                if(slidePics!=null && slidePics.length>0) {
                    mchInfo.setHead(slidePics[0]);
                }
            }
            mchDao.updateByPrimaryKeySelective(mchInfo);
        }
    }

    /**
     * 账单
     * @param param
     * @return
     */
    public Map<String, Object> bill(MchParam param){
        TokenUserVo tokenUser = userService.getTokenUser(param.getToken());
        param.setId(tokenUser.getMchId());
        Map<String, Object> map = new HashMap<>();
        MchBillVo billVo = new MchBillVo();
        // 总支出积分
        param.setType(2);
        MchBill bill = mchJifenDetailDao.sumBillJifenByMonth(param);
        if(bill!=null) {
            billVo.setYeji(bill.getYeji());
            billVo.setPayJifen(bill.getJifen());
        }
        // 总购买积分
        param.setType(1);
        bill = mchJifenDetailDao.sumBillJifenByMonth(param);
        if(bill!=null) {
            billVo.setBuyJifen(bill.getJifen());
        }
        map.put("bill", billVo);
        String curDate = param.getDate()+"-"+DateUtils.getCurDateDay();
        List<String> dayList = DateUtils.getDayListOfMonth(curDate);
        List<MchBillVo> daysBill = new ArrayList<>();
        param.setType(2);
        param.setDates(dayList);
        List<MchBill> payBills = mchJifenDetailDao.sumBillJifenByDays(param);
        param.setType(1);
        param.setDates(dayList);
        List<MchBill> buyBills = mchJifenDetailDao.sumBillJifenByDays(param);
        for (int i = 0; i < dayList.size(); i++) {
            String days = dayList.get(i);
            MchBill payBill = null;
            MchBill buyBill = null;
            for (int a = 0; a < payBills.size(); a++) {
                payBill = payBills.get(a);
                if(DateUtils.parse(payBill.getDate(), "yyyy-MM-dd").equals(days)){
                    break;
                }else{
                    payBill = null;
                }
            }
            for (int b = 0; b < buyBills.size(); b++) {
                buyBill = buyBills.get(b);
                if(DateUtils.parse(buyBill.getDate(), "yyyy-MM-dd").equals(days)){
                    break;
                }else{
                    buyBill = null;
                }
            }
            MchBillVo dayBill = new MchBillVo();
            dayBill.setDate(days);
            if(payBill!=null) {
                dayBill.setYeji(payBill.getYeji());
                dayBill.setPayJifen(payBill.getJifen());
            }
            if(buyBill!=null) {
                dayBill.setBuyJifen(buyBill.getJifen());
            }
            if(dayBill.getBuyJifen()!=0 || dayBill.getPayJifen()!=0){
                daysBill.add(dayBill);
            }
        }
        map.put("daysBill", daysBill);
        return map;
    }

    /**
     * 充值积分
     * @param tradeNo
     * @param outTradeNo
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void mchRecharge(String tradeNo, String outTradeNo){
        MchPay pay = mchPayDao.getByTradeNo(tradeNo);
        if(pay.getState()==0) {
            // 增加商家积分
            MchParam param = new MchParam();
            param.setJifenType(0);
            param.setId(pay.getUid());
            param.setJifen(pay.getJifen());
            mchDao.updateJifen(param);
            // 增加记录
            Mch mch = mchDao.selectByPrimaryKey(pay.getUid());
            MchJifenDetail detail = new MchJifenDetail();
            detail.setType(1);
            detail.setMchId(pay.getUid());
            detail.setJifen(pay.getJifen().doubleValue());
            detail.setGuid(mch.getAgentId());
            detail.setRemark("积分充值");
            detail.setCreateTime(DateUtils.getDate());
            mchJifenDetailDao.insertSelective(detail);
            // 邀请人收益=积分*1%
            if(mch.getInviter()!=null) {
                UserParam userParam = new UserParam();
                userParam.setId(mch.getInviter());
                userParam.setInviteProfit(pay.getJifen() * 0.01);
                userDao.addInviteProfit(userParam);
                UserInviteProfit inviteProfit = new UserInviteProfit();
                inviteProfit.setAmount(pay.getJifen() * 0.01);
                inviteProfit.setCreateTime(DateUtils.getDate());
                inviteProfit.setMchId(mch.getId());
                inviteProfit.setPayId(pay.getId());
                inviteProfit.setUid(mch.getInviter());
                userInviteProfitDao.insertSelective(inviteProfit);
            }
            // 更新交易
            MchPay mpPay = new MchPay();
            mpPay.setId(pay.getId());
            mpPay.setState(1);
            mpPay.setOutTradeNo(outTradeNo);
            mpPay.setUpdateTime(DateUtils.getDate());
            mchPayDao.updateByPrimaryKeySelective(mpPay);
        }
    }
}
